!
!     SORTer       Sort DAOPHOT files.
!     Copyright (C) 1997-9  Filip Hroch, Masaryk University, Brno, CZ
!
!===========================================================================
!
      subroutine  sorter (MAXSTR, watch,answer,which,file,outfile)
!
!=======================================================================
!
! Subroutine to read in any of the data files created by DAOPHOT and
! sort the stars according to magnitude, position, ID number,
! or OTHER.
!
!              OFFICIAL DAO VERSION:  1991 April 18
!
! Argument
!
!  WATCH (INPUT) governs whether information relating to the progress 
!        of the reductions is to be typed on the terminal screen
!        during execution.
!
! WATCH is a user-definable optional parameter.
!
!=======================================================================
! 
     implicit none
!
! Parameters
!
!    MAX is the number of different sorts which are possible
!        (currently 5: by ID number, by X, by Y, by magnitude, and
!         by OTHER [e.g. SHARP, ROUND, CHI, number of iterations]).
!
! MAXSTR is the maximum number of stars permitted in a data file.
!        It is limited by the size of the WORK array in DAOPHOT:
!        WORK must contain 282 bytes per star:  4 bytes each for SORT,
!        INDEX, NLINE1, and, NLINE2, and 133 bytes each for LINE1 and 
!        LINE2.
!
! MAXITM is the maximum number of output data per line of an output.
!        (currently 15, realized in PHOTOMETRY)
!
      integer :: MAXSTR
      integer, parameter :: MAXITM = 34
      integer, parameter :: MAXLEN = 135

      real :: datum(MAXITM),sort(MAXSTR)
      character(len=MAXLEN) :: text, work(MAXSTR,2)
      integer :: index(MAXSTR)

      character(len=*) :: file, outfile
      character :: answer
      real :: lobad, hibad, thresh, ap1, phpadu, readns, frad
      real :: watch, which, flip
      integer :: i, j, n, nl, ncol, nrow, istat, items, nstar
      integer :: mode
      
!
!-----------------------------------------------------------------------
!
! SECTION 1
!
! Get ready.
!
! Find out how the user wants to sort.
!
      if( watch > 0.5 )then
         write(*,"(11X, '   The following sorts are currently possible:')") 
         write(*,"(11X, '+/- 1  By increasing/decreasing star ID number')")
         write(*,"(11X, '+/- 2  By increasing/decreasing  X  coordinate')")
         write(*,"(11X, '+/- 3  By increasing/decreasing  Y  coordinate')")
         write(*,"(11X, '+/- 4  By increasing/decreasing magnitude')")
         write(*,"(11X, '+/- n  By increasing/decreasing OTHER (n <= ',I2,')')") maxitm
         write(*,*) nint(which)
      endif
 
!      CALL GETDAT ('Which do you want?', WHICH, 1)
      if (which < -1.e38) return                 ! CTRL-Z was entered

      mode = nint(which)
! Invalid response
      if ((abs(mode) < 1) .or. (abs(mode) > maxitm)) return                   
                  

      flip = mode/abs(mode)
      mode = abs(mode)
!
! Get input file name, open the file, and read its header.
!
!      FILE=' '
!  950 CALL GETNAM ('Input file name:', FILE)
!      IF ((FILE .EQ. 'END OF FILE') .OR. (FILE .EQ. 'GIVE UP')) RETURN
      call infile (2, file, istat)
      if (istat /= 0) then
         call stupid ('Error opening input file '//trim(file))
         return
      end if
!
! Get output file name and open the file.
!
!      FILE = SWITCH(FILE, CASE('.srt'))
!  960 CALL GETNAM ('Output file name:', FILE)
!      IF ((FILE .EQ. 'END OF FILE') .OR. (FILE .EQ. 'GIVE UP')) THEN
!         CALL CLFILE (2)
!         RETURN
!      END IF

      call outfil (3, outfile, istat)
      if (istat /= 0) then
         call stupid ('Error opening output file '//outfile)
         return
      end if

!      call GETYN ('Do you want the stars renumbered?', ANSWER)
      write(*,*) 'Do you want the stars renumbered? ', answer

      if (answer == 'E') then
         call clfile (2)
      end if

      nl = -1
      call rdhead (2, nl, ncol, nrow, lobad, hibad, thresh, ap1, phpadu, readns, frad)
      if (nl > 0) then                     ! header in input
         if (nl > 3) nl = 1
!
! Copy input file header to output file.  
!
         items = 6
         if (frad > 0.001) items = 7
         call wrhead (3, nl, ncol, nrow, items, lobad, hibad, thresh, ap1, phpadu, readns, frad)
      endif

      if (watch > 0.5) then
         if (mode <= 4) write (*,"(/22X,'STAR',6X,'X',8X,'Y',4X,'MAG.(1)')")
         if (mode >= 5) write (*,"(/17X,'STAR',6X,'X',8X,'Y',4X,'MAG.(1)',3X,'ITEM',I3)") mode
      endif
!
!-----------------------------------------------------------------------
!
! SECTION 2
!
! Read the input file in line by line, verbatim.  Pack the contents
! of the line into the REAL array WORK, keeping track of the
! lower and upper limits in the arrays LINELO and LINEHI.  At the
! same time, extract the the particular datum 
! according to which we wish to sort.  Sort these data.  Then write 
! the file out again, line by line, verbatim, but in the new order.
!
      i = 0

      do
         do
            call rdchar (2, text, n, istat)
            if (istat /= 0 .or. n > 0) exit        ! Blank line encountered
         enddo
         if (istat == 1) exit             ! END OF FILE
         if (istat /= 0) then
            call stupid ('Unable to read input file.')
            call clfile (2)
            return
         end if

      i = i + 1
      if (i > MAXSTR) then
         write (text,"(I10, ' stars is all I have room for.  Sorry!')") i - 1 
         call stupid (trim(text))
         call clfile (2)
         return
      end if

      read (text(2:), "(F5.0,14F9.0)", iostat=istat) (datum(j), j=1,(n-5)/9+1)
      if (istat /= 0) then
         call stupid ('Unable to read data from input file.')
         call clfile (2)
         return
      end if

      work(i,1) = text

      if (nl == 2) then

         do
            call rdchar (2, text, n, istat)
            if (istat /= 0) then
               call stupid ('Unable to read input file.')
               call clfile (2)
               return
            end if
            if (n > 0) exit
         enddo
         read (text(2:), "(F12.3, 2F6.3, 12(F8.3, 1X))", iostat=istat) (datum(j), j=16,19+(n-25)/9)
         if (istat /= 0) then
            call stupid ('Unable to read data from input file.')
            call clfile (2)
            return
         end if

         work(i,2) = text
      end if

      sort(i)=flip*datum(mode)
    enddo                                     ! End of input loop

!
! Perform the sort.
!
      nstar = i                                        ! number of stars
      call clfile (2)
      if (nstar <= 0) then
         call stupid ('No stars in input file.')
         return
      end if
      call quick(sort, nstar, index)
!
! the vector SORT is now arranged in order of increasing or decreasing
! whatever, and the vector INDEX now contains the ordinal position in
! the input file of the stars, in order of increasing or decreasing
! whatever.
!
! Now write the data out again.
!
      do i = 1, nstar
         j = index(i)
         if (nl /= 2) then
!
! If ID numbers are to be changed, insert the new ID into the text.
!
         if( answer == 'Y') write (work(j,1)(2:6),"(i5)") i
         write (3,"(a)") trim(work(j,1))
         if (watch > 0.5) then
            if (mode <= 4) then
              write(*,"(21x, a32)") work(j,1)(2:33)
            else
              write(*,"(16x, a32, 1x, f9.3)") work(j,1)(2:33), flip*sort(i)
            end if
         end if
      else
         if( answer == 'Y' ) write (work(j,1)(2:6),"(i5)") i
         write (3,"(a)") trim(work(j,1))
         if (watch > 0.5) then
            if (mode <= 4) then
               write (*,"(21x, a32)") work(j,1)(2:33)
            else
               write (*,"(16x, a32, 1x, f9.3)") work(j,1)(2:33), flip*sort(i)
            end if
         end if
         write (3, "(a)") trim(work(j,2))
         write (3,*) 
      end if
 enddo                                      ! End of output loop
!
!-----------------------------------------------------------------------
!
! Normal return.
!
      call clfile (3)
      return

      end!
